import dict from './dict';
import logger from './logger';
import fs from '@ohos.file.fs';
import current from './current';
import window from '@ohos.window';
import request from '@ohos.request';
import globalData from './globalData';
import CryptoJS from '@ohos/crypto-js';
import promptAction from '@ohos.promptAction';
import connection from '@ohos.net.connection';
import common from '@ohos.app.ability.common';
import notification from '@ohos.notificationManager';
import memoryImage from '../models/logic/memoryImage';
import { mangaType } from '../models/manga/mangaType';
import relationalStore from '@ohos.data.relationalStore';

class utils {
  readonly COLOR_WHITE = '#f4f4f4';
  readonly COLOR_BLACK = '#000000';

  remove<T>(arr: T[], obj: T) {
    try {
      let index = arr.indexOf(obj);
      arr.splice(index, 1);
    } catch (e) {
      logger.error(e);
    }
  }

  isMobileNetwork(): Promise<boolean> {
    return new Promise((resolve) => {
      try {
        connection.getDefaultNet().then((res) => {
          connection.getNetCapabilities(res).then((handle) => {
            let result = handle.bearerTypes.includes(connection.NetBearType.BEARER_CELLULAR);
            resolve(result);
          });
        });
      } catch (e) {
        logger.error(e);
        resolve(false);
      }
    });
  }

  mkdir(fd: string): Promise<boolean> {
    return new Promise((resolve) => {
      try {
        fs.access(fd, (err, res) => {
          if (!err) {
            if (!res)
              fs.mkdir(fd);
            resolve(true);
          } else {
            resolve(false);
            logger.error(JSON.stringify(err));
          }
        });
      } catch (e) {
        logger.error(e);
        resolve(false);
      }
    });
  }

  showNotify(title: string, content: string): number {
    try {
      if (!current.instance.notifyEnable)
        return -1;
      let id = globalData.notifyId;
      if (this.isEmpty(id))
        id = 1;
      else
        id++;
      let notificationRequest: notification.NotificationRequest = {
        id: id,
        content: {
          notificationContentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
          normal: {
            title: title,
            text: content
          }
        }
      };
      notification.publish(notificationRequest);
      return id;
    }
    catch (e) {
      logger.error(e);
      return -1;
    }
  }

  updateNotify(notifyId: number, title: string, content: string): number {
    try {
      if (notifyId != -1 && !current.instance.notifyEnable) {
        let notificationRequest: notification.NotificationRequest = {
          id: notifyId,
          content: {
            notificationContentType: notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
            normal: {
              title: title,
              text: content
            }
          }
        };
        notification.publish(notificationRequest);
      }
    } catch (e) {
      logger.error(e);
    }
    return notifyId;
  }

  setLayoutFullScreen(windowStage: window.WindowStage, statusBarColor: string, statusBarContentColor: string,
                      navigationBarColor: string, navigationBarContentColor: string) {
    try {
      let windowClass = null;
      windowStage.getMainWindow((err, data) => {
        if (err.code) return;
        windowClass = data;
        let isLayoutFullScreen = false;
        windowClass.setWindowLayoutFullScreen(isLayoutFullScreen);
        let sysBarProps = {
          statusBarColor: statusBarColor,
          statusBarContentColor: statusBarContentColor,
          navigationBarColor: navigationBarColor,
          navigationBarContentColor: navigationBarContentColor
        };
        windowClass.setWindowSystemBarProperties(sysBarProps);
      })
    } catch (e) {
      logger.error(e);
    }
  }

  buvId(): string {
    try {
      let mac = [];
      for (let i = 0; i < 6; i++) {
        let min = Math.min(0, 0xff)
        let max = Math.max(0, 0xff)
        let num = parseInt((Math.random() * (min - max + 1) + max).toString()).toString(16)
        mac.push(num)
      }
      let md5 = this.md5(mac.join(':'));
      let md5Arr = md5.split('');
      return `XY${md5Arr[2]}${md5Arr[12]}${md5Arr[22]}${md5}`;
    } catch (e) {
      logger.error(e);
    }
  }

  md5(str): string {
    return CryptoJS.MD5(str).toString();
  }

  parseObject(str: string) {
    try {
      return JSON.parse(str);
    } catch (e) {
      logger.error(e);
    }
    return '';
  }

  isEmpty(obj): boolean {
    return (obj === undefined || obj === null || obj === '');
  }

  isEmptyArr(array): boolean {
    return (this.isEmpty(array) || array.length === 0);
  }

  showPopup(msg: string, duration?: number) {
    try {
      if (this.isEmpty(duration))
        duration = 2000;
      promptAction.showToast({
        message: msg,
        duration: duration,
      });
    } catch (e) {
      logger.error(e);
    }
  }

  getQuery(url: string) {
    try {
      let index = url.indexOf('?');
      if (index > 0)
        return url.substring(index);
    } catch (e) {
      logger.error(e);
    }
    return '';
  }

  selectName(source) {
    let idx = 0;
    let array = [];
    try {
      source?.forEach(item => {
        array[idx] = {
          value: item.name
        };
        idx++;
      });
    } catch (e) {
      logger.error(e);
    }
    return array;
  }

  takeId(source: mangaType, areasPos: string, statusPos: string, stylesPos: string, ordersPos: string, pricesPos: string): number[] {
    let style = source.styles.find(item => item.name == stylesPos);
    let area = source.areas.find(item => item.name == areasPos);
    let status = source.status.find(item => item.name == statusPos);
    let order = source.orders.find(item => item.name == ordersPos);
    let price = source.prices.find(item => item.name == pricesPos);
    return [style.id, area.id, status.id, order.id, price.id];
  }

  getRandomInt(randomNumber: number): number {
    let roundNumber: number = Math.round(Math.random() * dict.MULTIPLY_TEN);
    if (roundNumber === randomNumber)
      roundNumber = this.getRandomInt(randomNumber);
    return roundNumber;
  }

  async createRdbStore(context: common.Context) {
    try {
      if (this.isEmpty(globalData.rdbStore)) {
        await relationalStore.getRdbStore(context, dict.STORE_CONFIG).then((rdbStore: relationalStore.RdbStore) => {
          if (!this.isEmpty(rdbStore)) {
            rdbStore.executeSql(dict.CREATE_TABLE_FORM);
            globalData.rdbStore = rdbStore;
          }
        });
      }
    } catch (e) {
      logger.error(e);
    }
    return globalData.rdbStore;
  }

  buildMemoryImage(context: common.Context, urls: Array<string>): Promise<Array<memoryImage>> {
    let arr: Array<memoryImage> = [];
    return new Promise((resolve) => {
      try {
        for (let url of urls) {
          this.download(context, 0, url).then((mi) => {
            arr.push(mi);
            if (arr.length == urls.length)
              resolve(arr);
          });
        }
      } catch (e) {
        logger.error(e);
        resolve(arr);
      }
    });
  }

  private download(context: common.Context, idx: number, url: string): Promise<memoryImage> {
    return new Promise((resolve) => {
      try {
        let tempDir = context.getApplicationContext().tempDir;
        let rnd = Math.floor((Math.random() * 100) + 1);
        let fileName = `file${Date.now()}${rnd}`;
        let tmpFile = `${tempDir}/${fileName}`;
        request.downloadFile(context, {
          url: url, filePath: tmpFile, enableMetered: true, enableRoaming: true
        }).then((task) => {
          task.on('complete', function callback() {
            fs.open(tmpFile).then((file) => {
              let info = new memoryImage(idx, file.fd, fileName);
              resolve(info);
            });
          });
          task.on('fail', function callBack(err) {
            logger.info('ArkTSCard download task failed. Cause:' + err);
            resolve(new memoryImage());
          });
        }).catch((res) => {
          logger.error(res);
          resolve(new memoryImage());
        });
      } catch (e) {
        logger.error(e);
        resolve(new memoryImage());
      }
    });
  }
}
export default new utils();